{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "id": "S97D7gQHMdG_"
   },
   "outputs": [],
   "source": [
    "##### Copyright 2021 The Cirq Developers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "cellView": "form",
    "id": "Y6Wh1qtGMghL"
   },
   "outputs": [],
   "source": [
    "# @title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
    "# you may not use this file except in compliance with the License.\n",
    "# You may obtain a copy of the License at\n",
    "#\n",
    "# https://www.apache.org/licenses/LICENSE-2.0\n",
    "#\n",
    "# Unless required by applicable law or agreed to in writing, software\n",
    "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
    "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
    "# See the License for the specific language governing permissions and\n",
    "# limitations under the License."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "gNBCrapEMgxB"
   },
   "source": [
    "# Circuit optimization, gate alignment, and spin echoes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "tlnEweYsMgzj"
   },
   "source": [
    "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://quantumai.google/cirq/tutorials/google/spin_echoes\"><img src=\"https://quantumai.google/site-assets/images/buttons/quantumai_logo_1x.png\" />View on QuantumAI</a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/quantumlib/Cirq/blob/main/docs/tutorials/google/spin_echoes.ipynb\"><img src=\"https://quantumai.google/site-assets/images/buttons/colab_logo_1x.png\" />Run in Google Colab</a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://github.com/quantumlib/Cirq/blob/main/docs/tutorials/google/spin_echoes.ipynb\"><img src=\"https://quantumai.google/site-assets/images/buttons/github_logo_1x.png\" />View source on GitHub</a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a href=\"https://storage.googleapis.com/tensorflow_docs/Cirq/docs/tutorials/google/spin_echoes.ipynb\"><img src=\"https://quantumai.google/site-assets/images/buttons/download_icon_1x.png\" />Download notebook</a>\n",
    "  </td>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "PnYvZgIoMg2O"
   },
   "source": [
    "This tutorial shows how to prepare circuits to run on the Quantum Computing Service (QCS) and optimize them to improve performace, showing an example of the procedure outlined in the [Best practices guide](https://quantumai.google/cirq/google/best_practices#improving_circuit_fidelity). This is an \"advanced\" tutorial where you will learn to perform the following optimization techniques:\n",
    "\n",
    "1. Converting to target gateset\n",
    "2. Ejecting single-qubit operations\n",
    "3. Aligning gates in moments\n",
    "4. Inserting spin echoes to reduce leakage & cross-talk."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "BRfLi9YSMg4v"
   },
   "source": [
    "## Setup\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "id": "JolZGos2MhDM"
   },
   "outputs": [],
   "source": [
    "try:\n",
    "    import cirq\n",
    "except ImportError:\n",
    "    print(\"installing cirq...\")\n",
    "    !pip install --quiet cirq\n",
    "    print(\"installed cirq.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "id": "lFI7APiqMhFy"
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "import cirq\n",
    "import cirq_google as cg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "cellView": "form",
    "id": "-x_6wT1yRFYh"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Getting OAuth2 credentials.\n",
      "Press enter after entering the verification code.\n",
      "Authentication complete.\n",
      "Successful authentication to Google Cloud.\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "\n",
    "# The Google Cloud Project id to use.\n",
    "project_id = ''  # @param {type:\"string\"}\n",
    "processor_id = \"\"  # @param {type:\"string\"}\n",
    "\n",
    "from cirq_google.engine.qcs_notebook import get_qcs_objects_for_notebook\n",
    "\n",
    "device_sampler = get_qcs_objects_for_notebook(project_id, processor_id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "cellView": "form",
    "id": "H6QoxTf1WaPn"
   },
   "outputs": [],
   "source": [
    "# @markdown Helper functions.\n",
    "from typing import Sequence\n",
    "from cirq.experiments import random_rotations_between_grid_interaction_layers_circuit\n",
    "\n",
    "\n",
    "# Gates for spin echoes.\n",
    "pi_pulses = [cirq.PhasedXPowGate(phase_exponent=p, exponent=1.0) for p in (-0.5, 0.0, 0.5, 1.0)]\n",
    "\n",
    "\n",
    "def create_benchmark_circuit(\n",
    "    qubits: Sequence[cirq.GridQubit],\n",
    "    cycles: int,\n",
    "    twoq_gate: cirq.Gate = cirq.SQRT_ISWAP,\n",
    "    seed: int | None = None,\n",
    "    with_optimization: bool = False,\n",
    "    with_alignment: bool = False,\n",
    "    with_spin_echoes: bool = False,\n",
    ") -> cirq.Circuit:\n",
    "    \"\"\"Returns an \"OTOC-like\" circuit [1] used to benchmark optimization and/or\n",
    "    alignment and/or spin echoes.\n",
    "\n",
    "    Args:\n",
    "        qubits: Qubits to use.\n",
    "        cycles: Depth of random rotations in the forward & reverse unitary.\n",
    "        twoq_gate: Two-qubit gate to use.\n",
    "        seed: Seed for circuit generation.\n",
    "        with_optimization: Run a series of optimizations on the circuit.\n",
    "        with_alignment: Align moments and synchronize terminal measurements.\n",
    "        with_spin_echoes: Insert spin echoes on ancilla qubit.\n",
    "\n",
    "    References:\n",
    "        [1] Fig. S10 of https://arxiv.org/abs/2101.08870.\n",
    "    \"\"\"\n",
    "    ancilla, qubits = qubits[0], qubits[1:]\n",
    "\n",
    "    # Put ancilla into the |1⟩ state and couple it to the rest of the qubits.\n",
    "    excite_ancilla = [cirq.X(ancilla), twoq_gate(ancilla, qubits[0])]\n",
    "\n",
    "    # Forward operations.\n",
    "    forward = random_rotations_between_grid_interaction_layers_circuit(\n",
    "        qubits,\n",
    "        depth=cycles,\n",
    "        two_qubit_op_factory=lambda a, b, _: twoq_gate.on(a, b),\n",
    "        pattern=cirq.experiments.GRID_STAGGERED_PATTERN,\n",
    "        single_qubit_gates=[\n",
    "            cirq.PhasedXPowGate(phase_exponent=p, exponent=0.5) for p in np.arange(-1.0, 1.0, 0.25)\n",
    "        ],\n",
    "        seed=seed,\n",
    "    )\n",
    "\n",
    "    # Full circuit. Note: We are intentionally creating a bad circuit structure\n",
    "    # by putting each operation in a new moment (via `cirq.InsertStrategy.New`)\n",
    "    # to show the advantages of optimization & alignment.\n",
    "    circuit = cirq.Circuit(excite_ancilla)\n",
    "    circuit.append(forward.all_operations(), strategy=cirq.InsertStrategy.NEW)\n",
    "    circuit.append(cirq.inverse(forward).all_operations(), strategy=cirq.InsertStrategy.NEW)\n",
    "    circuit.append(cirq.inverse(excite_ancilla[1:]))\n",
    "    circuit.append(cirq.measure(ancilla, key=\"z\"), strategy=cirq.InsertStrategy.NEW)\n",
    "\n",
    "    # Run optimization.\n",
    "    if with_optimization:\n",
    "        cirq.MergeInteractionsToSqrtIswap().optimize_circuit(circuit)\n",
    "        circuit = cirq.eject_phased_paulis(circuit)\n",
    "        circuit = cirq.eject_z(circuit)\n",
    "        circuit = cirq.drop_negligible_operations(circuit)\n",
    "        circuit = cirq.drop_empty_moments(circuit)\n",
    "\n",
    "    # Insert spin echoes. Note: It's important to do this after optimization, as\n",
    "    # optimization will remove spin echoes.\n",
    "    if with_spin_echoes:\n",
    "        random_state = np.random.RandomState(seed)\n",
    "\n",
    "        spin_echo = []\n",
    "        for _ in range(cycles * 2):\n",
    "            op = random_state.choice(pi_pulses).on(ancilla)\n",
    "            spin_echo += [op, cirq.inverse(op)]\n",
    "\n",
    "        circuit.insert(2, spin_echo)\n",
    "\n",
    "    # Alignment.\n",
    "    if with_alignment:\n",
    "        circuit = cirq.align_right(circuit)\n",
    "        circuit = synchronize_terminal_measurements(circuit)\n",
    "\n",
    "    return circuit\n",
    "\n",
    "\n",
    "def to_survival_prob(result: cirq.Result) -> float:\n",
    "    return np.mean(np.sum(result.measurements[\"z\"], axis=1) == 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "be9PReoRVYsB"
   },
   "source": [
    "## Preparing circuits to run on QCS"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "afa-MP4Qqd6C"
   },
   "source": [
    "For the sake of this tutorial, we will use a circuit structure created by the `create_benchmark_circuit` function defined above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "id": "LubPWNqUVikD"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Example benchmark circuit:\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">(0, 0): ───X───iSwap────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap──────────────────────────────────────────────────────────M(&#x27;z&#x27;)───\n",
       "               │                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        │\n",
       "(0, 1): ───────iSwap───PhX(0.25)^0.5──────────────────────────────────────────────────────────────────────PhX(-0.75)^0.5─────────────────────────────────────────────────────────────────iSwap───PhX(0.75)^0.5──────────────────────────────────────────────────────────────iSwap───────────PhX(0.25)^0.5──────────────────────────────────────────────────────────────PhX(0.25)^-0.5──────────────────────────────────────────────────────────────────iSwap─────────────────PhX(0.75)^-0.5──────────────────────────────────────────────────────────────────iSwap──────PhX(-0.75)^-0.5────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5───iSwap^-1────────────────────────────────────────────────────────────────\n",
       "                                                                                                                                                                                         │                                                                                  │                                                                                                                                                                          │                                                                                                     │\n",
       "(0, 2): ───────────────────────────────PhX(-0.25)^0.5─────────────────────────────────────────────iSwap────────────────────PhX(0.25)^0.5─────────────────────────────────────────────────┼───────────────────────PhX(0)^0.5─────────────────────────────────────────────────iSwap───────────────────────────PhX(-0.5)^0.5───────────────────────────────────────────────────────────────PhX(-0.5)^-0.5─────────────────────────────────────────────────iSwap^-1───────────────────────────────PhX(0)^-0.5────────────────────────────────────────────────────┼────────────────────────────PhX(0.25)^-0.5────────────────────────────────────────────────────iSwap───────────────────────PhX(-0.25)^-0.5─────────────────────────────────────────────────────────\n",
       "                                                                                                  │                                                                                      │                                                                                                                                                                                                                                                                                                                                                                   │                                                                                              │\n",
       "(1, 0): ────────────────────────────────────────────────PhX(0)^0.5────────────────────────────────┼────────────────────────────────────────PhX(0.75)^0.5─────────────────────────────────┼────────────────────────────────────PhX(0.5)^0.5──────────────────────────────────────────iSwap───────────────────────────────────PhX(0)^0.5───────────────────────────────────────────────────────────────────PhX(0)^-0.5──────────────────────────────────────────────iSwap─────────────────────────────────────PhX(0.5)^-0.5────────────────────────────────────┼─────────────────────────────────────────────PhX(0.75)^-0.5───────────────────────────────────┼─────────────────────────────────────────────PhX(0)^-0.5───────────────────────────────────────────\n",
       "                                                                                                  │                                                                                      │                                                                                          │                                                                                                                                                                             │                                                                                          │                                                                                              │\n",
       "(1, 1): ─────────────────────────────────────────────────────────────PhX(1)^0.5───────────────────┼────────────────────────────────────────────────────────PhX(-0.75)^0.5────────────────iSwap───────────────────────────────────────────────PhX(-0.5)^0.5──────────────────────────iSwap────────────────────────────────────────────────PhX(-0.25)^0.5────────────────────────────────────────────────────────────────PhX(-0.25)^-0.5────────────────────────────iSwap^-1──────────────────────────────────────────────────PhX(-0.5)^-0.5───────────────────iSwap^-1───────────────────────────────────────────────────────PhX(-0.75)^-0.5─────────────────┼───────────────────────────────────────────────────────────PhX(1)^-0.5─────────────────────────────\n",
       "                                                                                                  │                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         │\n",
       "(1, 2): ──────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5───iSwap─────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────────────────────────────────────────────────────────PhX(0.5)^0.5─────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5─────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────────────────────────────────PhX(0.5)^-0.5────────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5───iSwap^-1──────────────────────────────────────────────────────────────────PhX(0.75)^-0.5────────────</pre>"
      ],
      "text/plain": [
       "(0, 0): ───X───iSwap────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap──────────────────────────────────────────────────────────M('z')───\n",
       "               │                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        │\n",
       "(0, 1): ───────iSwap───PhX(0.25)^0.5──────────────────────────────────────────────────────────────────────PhX(-0.75)^0.5─────────────────────────────────────────────────────────────────iSwap───PhX(0.75)^0.5──────────────────────────────────────────────────────────────iSwap───────────PhX(0.25)^0.5──────────────────────────────────────────────────────────────PhX(0.25)^-0.5──────────────────────────────────────────────────────────────────iSwap─────────────────PhX(0.75)^-0.5──────────────────────────────────────────────────────────────────iSwap──────PhX(-0.75)^-0.5────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5───iSwap^-1────────────────────────────────────────────────────────────────\n",
       "                                                                                                                                                                                         │                                                                                  │                                                                                                                                                                          │                                                                                                     │\n",
       "(0, 2): ───────────────────────────────PhX(-0.25)^0.5─────────────────────────────────────────────iSwap────────────────────PhX(0.25)^0.5─────────────────────────────────────────────────┼───────────────────────PhX(0)^0.5─────────────────────────────────────────────────iSwap───────────────────────────PhX(-0.5)^0.5───────────────────────────────────────────────────────────────PhX(-0.5)^-0.5─────────────────────────────────────────────────iSwap^-1───────────────────────────────PhX(0)^-0.5────────────────────────────────────────────────────┼────────────────────────────PhX(0.25)^-0.5────────────────────────────────────────────────────iSwap───────────────────────PhX(-0.25)^-0.5─────────────────────────────────────────────────────────\n",
       "                                                                                                  │                                                                                      │                                                                                                                                                                                                                                                                                                                                                                   │                                                                                              │\n",
       "(1, 0): ────────────────────────────────────────────────PhX(0)^0.5────────────────────────────────┼────────────────────────────────────────PhX(0.75)^0.5─────────────────────────────────┼────────────────────────────────────PhX(0.5)^0.5──────────────────────────────────────────iSwap───────────────────────────────────PhX(0)^0.5───────────────────────────────────────────────────────────────────PhX(0)^-0.5──────────────────────────────────────────────iSwap─────────────────────────────────────PhX(0.5)^-0.5────────────────────────────────────┼─────────────────────────────────────────────PhX(0.75)^-0.5───────────────────────────────────┼─────────────────────────────────────────────PhX(0)^-0.5───────────────────────────────────────────\n",
       "                                                                                                  │                                                                                      │                                                                                          │                                                                                                                                                                             │                                                                                          │                                                                                              │\n",
       "(1, 1): ─────────────────────────────────────────────────────────────PhX(1)^0.5───────────────────┼────────────────────────────────────────────────────────PhX(-0.75)^0.5────────────────iSwap───────────────────────────────────────────────PhX(-0.5)^0.5──────────────────────────iSwap────────────────────────────────────────────────PhX(-0.25)^0.5────────────────────────────────────────────────────────────────PhX(-0.25)^-0.5────────────────────────────iSwap^-1──────────────────────────────────────────────────PhX(-0.5)^-0.5───────────────────iSwap^-1───────────────────────────────────────────────────────PhX(-0.75)^-0.5─────────────────┼───────────────────────────────────────────────────────────PhX(1)^-0.5─────────────────────────────\n",
       "                                                                                                  │                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         │\n",
       "(1, 2): ──────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5───iSwap─────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────────────────────────────────────────────────────────PhX(0.5)^0.5─────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5─────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────────────────────────────────PhX(0.5)^-0.5────────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5───iSwap^-1──────────────────────────────────────────────────────────────────PhX(0.75)^-0.5────────────"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"\"\"Create an example circuit.\"\"\"\n",
    "\n",
    "qubits = cirq.GridQubit.rect(\n",
    "    2, 3\n",
    ")  # [cirq.GridQubit(x, y) for (x, y) in [(3, 2), (4, 2), (4, 1), (5, 1), (6, 1), (6, 2), (5, 2)]]\n",
    "circuit = create_benchmark_circuit(qubits, twoq_gate=cirq.ISWAP, cycles=3, seed=1)\n",
    "\n",
    "print(\"Example benchmark circuit:\\n\")\n",
    "circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ojDozjQK7cos"
   },
   "source": [
    "This circuit divides the qubits into two registers: a single ancilla (top qubit) as the first register, and the remaining qubits as the second register. First, the ancilla is excited into the $|1\\rangle$ state and coupled to the second register. Then, a [Loschmidt echo](https://quantumai.google/cirq/tutorials/google/echoes) is performed on the second register. Last, the ancilla is uncoupled from the second register and measured. Without any noise, the only measurement result should be $1$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "id": "nooNt8bi8NKH"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Counter({1: 1000})"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"\"\"Without noise, only the 1 state is measured.\"\"\"\n",
    "\n",
    "result = cirq.Simulator().run(circuit, repetitions=1000)\n",
    "result.histogram(key=\"z\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "aA5wUJa38VyO"
   },
   "source": [
    "We choose this circuit as an example for two reasons:\n",
    "\n",
    "1. Each gate in the circuit is in its own `cirq.Moment`, so this is a poor circuit structure to run on devices without any optimization / alignment.\n",
    "\n",
    "2. The ancilla qubit is idle except at the start and end of the circuit, so this is a prime example where adding spin echoes can improve performance.\n",
    "\n",
    "A similar circuit was used in [Information Scrambling in Computationally Complex Quantum Circuits](https://arxiv.org/abs/2101.08870) (see Fig. S10) to benchmark the performance of spin echoes.\n",
    "\n",
    "Starting from this circuit, we show how to optimize gates, align moments, and insert spin echoes to improve the performance on a real device."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "pQXwGBdO-iS4"
   },
   "source": [
    "### Convert to target gateset"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "szjI2vm2VbN4"
   },
   "source": [
    "To run on a device, all gates in the circuit will be converted to a gateset supported by that device. (See the [Device specifications guide](https://quantumai.google/cirq/google/specification) for information on supported gatesets.)\n",
    "\n",
    "We will use the $\\sqrt{\\text{iSWAP}}$ gateset in this tutorial. You can see this gateset and others as follows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "id": "Hyky31J08kWK"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sycamore\n",
      "-------\n",
      "syc 12000\n",
      "xy 25000\n",
      "xy_pi 25000\n",
      "xy_half_pi 25000\n",
      "z 0\n",
      "xyz 25000\n",
      "meas 4000000\n",
      "wait 0\n",
      "\n",
      "sqrt_iswap\n",
      "-------\n",
      "fsim_pi_4 32000\n",
      "inv_fsim_pi_4 32000\n",
      "xy 25000\n",
      "z 0\n",
      "xyz 25000\n",
      "meas 4000000\n",
      "wait 0\n",
      "\n",
      "fsim\n",
      "-------\n",
      "fsim 0\n",
      "xy 25000\n",
      "z 0\n",
      "xyz 25000\n",
      "meas 4000000\n",
      "wait 0\n",
      "\n",
      "xmon\n",
      "-------\n",
      "xy 25000\n",
      "z 0\n",
      "xyz 25000\n",
      "cz 0\n",
      "meas 4000000\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Create an Engine object to use.\n",
    "spec = cg.Engine(project_id).get_processor(processor_id).get_device_specification()\n",
    "\n",
    "# Iterate through each gate set valid on the device.\n",
    "for gateset in spec.valid_gate_sets:\n",
    "    print(gateset.name)\n",
    "    print('-------')\n",
    "    # Prints each gate valid in the set with its duration\n",
    "    for gate in gateset.valid_gates:\n",
    "        print('%s %d' % (gate.id, gate.gate_duration_picos))\n",
    "    print()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Tf5O4HxH8qBg"
   },
   "source": [
    "To convert gates to this gateset, use the `cirq.MergeInteractionsToSqrtIswap` optimizer. This optimizer merges all consecutive (one- and two-qubit) interactions on two qubits into a unitary matrix and then decomposes this unitary using $\\sqrt{\\text{iSWAP}}$ gates in an attempt to (a) convert to the target gateset and (b) reduce the circuit depth by reducing the number of operations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "id": "Eb4NyHFT-l4-"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">                                                                                                                                                                                 ┌─────────────────────┐                                                                                                                                                              ┌───────────────────────┐   ┌───────────────────────┐                                                             ┌────────────────────┐\n",
       "(0, 0): ───X───X───S───iSwap────────────iSwap────────Z──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S────────────iSwap───────────────────iSwap─────────Z───────M(&#x27;z&#x27;)───\n",
       "                       │                │                                                                                                                                                                                                                                                                                                                                                                                                                                                │                       │\n",
       "(0, 1): ───────────────iSwap^0.5────────iSwap^0.5────X────────────S^-1────────────────────────────────────────────────────────────────────────────────────X───S^-1───iSwap────────────────────iSwap────────T───X^0.5───Z^0.75───T────────X^0.5────T^-1──────────────────────────────────────────────────────────────────────────────────────────────────X───Z^0.118──────────────────iSwap───────────────────────iSwap───────────────────────────────────────────────────────────────────iSwap^0.5───────────────iSwap^0.5─────S────────────────\n",
       "                                                                                                                                                                     │                        │                                                                                                                                                                                      │                           │\n",
       "(0, 2): ───────────────PhX(-0.25)^0.5─────────────────────────────────────────────Z^-0.145───iSwap───────iSwap───────T───────────────X^0.75───────────S──────────────┼────────────────────────┼─────────────────────────────────X^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5┼───────────────────────────┼─────────────────────────────────────X─────────Z^-0.016───iSwap───────────────────iSwap────────Z^-0.75───────X^0.5───Z^0.75───\n",
       "                                                                                             │           │                                                           │                        │                                                                                                                                                                                      │                           │                                                          │                       │\n",
       "(1, 0): ────────────────────────────────PhX(0)^0.5───────────────────────────────────────────┼───────────┼───────────PhX(0.75)^0.5───────────────────────────────────┼────────────PhX(0.5)^0.5┼──────────────────────────────────────────Y^-0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────────PhX(0.75)^-0.5┼──────────────────────────────────────────────────────────┼────────────PhX(0)^-0.5┼───────────────────────────────────────────\n",
       "                                                                                             │           │                                                           │                        │                                                                                                                                                                                      │                           │                                                          │                       │\n",
       "(1, 1): ─────────────────────────────────────────────PhX(1)^0.5──────────────────────────────┼───────────┼───────────────────────────PhX(-0.75)^0.5──────────────────iSwap^0.5────────────────iSwap^0.5────S───Y^0.5─────────────────────Y^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap^0.5───────────────────iSwap^0.5────Z^-0.868───X^0.5─────────Z^-0.75──────────────┼───────────────────────┼────────────PhX(1)^-0.5────────────────────\n",
       "                                                                                             │           │                                                                                                                                                                                                                                                                                                                                                                  │                       │\n",
       "(1, 2): ──────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────iSwap^0.5───iSwap^0.5───Z^-0.355────────X^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────PhX(0)^-0.5───────────────────────────PhX(0.5)^-0.5────────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5────────────────────────iSwap^0.5───────────────iSwap^0.5────Z^0.766───────X^0.5───Z^0.75───\n",
       "                                                                                                                                                                                 └─────────────────────┘                                                                                                                                                              └───────────────────────┘   └───────────────────────┘                                                             └────────────────────┘</pre>"
      ],
      "text/plain": [
       "                                                                                                                                                                                 ┌─────────────────────┐                                                                                                                                                              ┌───────────────────────┐   ┌───────────────────────┐                                                             ┌────────────────────┐\n",
       "(0, 0): ───X───X───S───iSwap────────────iSwap────────Z──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S────────────iSwap───────────────────iSwap─────────Z───────M('z')───\n",
       "                       │                │                                                                                                                                                                                                                                                                                                                                                                                                                                                │                       │\n",
       "(0, 1): ───────────────iSwap^0.5────────iSwap^0.5────X────────────S^-1────────────────────────────────────────────────────────────────────────────────────X───S^-1───iSwap────────────────────iSwap────────T───X^0.5───Z^0.75───T────────X^0.5────T^-1──────────────────────────────────────────────────────────────────────────────────────────────────X───Z^0.118──────────────────iSwap───────────────────────iSwap───────────────────────────────────────────────────────────────────iSwap^0.5───────────────iSwap^0.5─────S────────────────\n",
       "                                                                                                                                                                     │                        │                                                                                                                                                                                      │                           │\n",
       "(0, 2): ───────────────PhX(-0.25)^0.5─────────────────────────────────────────────Z^-0.145───iSwap───────iSwap───────T───────────────X^0.75───────────S──────────────┼────────────────────────┼─────────────────────────────────X^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5┼───────────────────────────┼─────────────────────────────────────X─────────Z^-0.016───iSwap───────────────────iSwap────────Z^-0.75───────X^0.5───Z^0.75───\n",
       "                                                                                             │           │                                                           │                        │                                                                                                                                                                                      │                           │                                                          │                       │\n",
       "(1, 0): ────────────────────────────────PhX(0)^0.5───────────────────────────────────────────┼───────────┼───────────PhX(0.75)^0.5───────────────────────────────────┼────────────PhX(0.5)^0.5┼──────────────────────────────────────────Y^-0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────────PhX(0.75)^-0.5┼──────────────────────────────────────────────────────────┼────────────PhX(0)^-0.5┼───────────────────────────────────────────\n",
       "                                                                                             │           │                                                           │                        │                                                                                                                                                                                      │                           │                                                          │                       │\n",
       "(1, 1): ─────────────────────────────────────────────PhX(1)^0.5──────────────────────────────┼───────────┼───────────────────────────PhX(-0.75)^0.5──────────────────iSwap^0.5────────────────iSwap^0.5────S───Y^0.5─────────────────────Y^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap^0.5───────────────────iSwap^0.5────Z^-0.868───X^0.5─────────Z^-0.75──────────────┼───────────────────────┼────────────PhX(1)^-0.5────────────────────\n",
       "                                                                                             │           │                                                                                                                                                                                                                                                                                                                                                                  │                       │\n",
       "(1, 2): ──────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────iSwap^0.5───iSwap^0.5───Z^-0.355────────X^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────PhX(0)^-0.5───────────────────────────PhX(0.5)^-0.5────────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5────────────────────────iSwap^0.5───────────────iSwap^0.5────Z^0.766───────X^0.5───Z^0.75───\n",
       "                                                                                                                                                                                 └─────────────────────┘                                                                                                                                                              └───────────────────────┘   └───────────────────────┘                                                             └────────────────────┘"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cirq.MergeInteractionsToSqrtIswap().optimize_circuit(circuit)\n",
    "circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "RXBNzJKXG_Oi"
   },
   "source": [
    "Note: Cirq supports decomposing to many different target gatesets via analytical decomposition functions present in `cirq.optimizers`. For example, you can compile an arbitrary two-qubit unitary (provided as a matrix) to $\\sqrt{\\text{iSWAP}}$ operations as shown below. This is useful when using custom gates in a circuit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "id": "cOoSlIZlEjci"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">(0, 0): ───Z^0.07────X^0.501───Z^0.424───iSwap───────Z^(1/6)────X^0.022───Z^-0.217───iSwap───────Z^0.983────X^0.603───Z^-0.78───\n",
       "                                         │                                           │\n",
       "(0, 1): ───Z^0.543───X^0.26──────────────iSwap^0.5───Z^(5/13)───X^(1/3)──────────────iSwap^0.5───Z^-0.367───X^0.114───Z^0.18────</pre>"
      ],
      "text/plain": [
       "(0, 0): ───Z^0.07────X^0.501───Z^0.424───iSwap───────Z^(1/6)────X^0.022───Z^-0.217───iSwap───────Z^0.983────X^0.603───Z^-0.78───\n",
       "                                         │                                           │\n",
       "(0, 1): ───Z^0.543───X^0.26──────────────iSwap^0.5───Z^(5/13)───X^(1/3)──────────────iSwap^0.5───Z^-0.367───X^0.114───Z^0.18────"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"\"\"Compile an arbitrary two-qubit operation to the sqrt_iswap gateset.\"\"\"\n",
    "\n",
    "ops = cirq.two_qubit_matrix_to_sqrt_iswap_operations(\n",
    "    q0=qubits[0], q1=qubits[1], mat=cirq.testing.random_unitary(dim=4, random_state=1)\n",
    ")\n",
    "cirq.Circuit(ops)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "OMRtgOHh-mDj"
   },
   "source": [
    "### Eject single-qubit operations"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "4mYaNbqxBDBp"
   },
   "source": [
    "After converting to a target gateset, you can use various circuit optimizers to attempt to reduce the number of gates as shown below."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "DiR_6NvV_mb6"
   },
   "source": [
    "The `cirq.eject_phased_paulis` optimizer pushes `cirq.X`, `cirq.Y`, and `cirq.PhasedXPowGate` gates towards the end of the circuit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "id": "KnJXHJNe-mha"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">                                                                                                                                                                                 ┌─────────────────────┐                                                                                                                                                                  ┌───────────────────────┐   ┌───────────────────────┐                                                                  ┌────────────────────┐\n",
       "(0, 0): ───────────S───iSwap────────────iSwap────────Z───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S────────────iSwap───────────────────iSwap─────────Z───────M(&#x27;z&#x27;)───\n",
       "                       │                │                                                                                                                                                                                                                                                                                                                                                                                                                                                         │                       │\n",
       "(0, 1): ───────────────iSwap^0.5────────iSwap^0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────S───S^-1───iSwap────────────────────iSwap────────T───X^0.5───Z^0.75───T────────X^0.5────T^-1──────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.0592)──────────────────iSwap───────────────────────iSwap────────────────────────────────────────────────────────────────────────iSwap^0.5───────────────iSwap^0.5─────S────────────────\n",
       "                                                                                                                                                                     │                        │                                                                                                                                                                                          │                           │\n",
       "(0, 2): ───────────────PhX(-0.25)^0.5─────────────────────────────────────────────Z^-0.145───iSwap───────iSwap───────T───────────────X^0.75───────────S──────────────┼────────────────────────┼─────────────────────────────────X^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5┼───────────────────────────┼───────────────────────────────────────────────PhX(-0.00809)───iSwap───────────────────iSwap────────Z^-0.75───────X^0.5───Z^0.75───\n",
       "                                                                                             │           │                                                           │                        │                                                                                                                                                                                          │                           │                                                               │                       │\n",
       "(1, 0): ────────────────────────────────PhX(0)^0.5───────────────────────────────────────────┼───────────┼───────────PhX(0.75)^0.5───────────────────────────────────┼────────────PhX(0.5)^0.5┼──────────────────────────────────────────Y^-0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────────PhX(0.75)^-0.5┼───────────────────────────────────────────────────────────────┼────────────PhX(0)^-0.5┼───────────────────────────────────────────\n",
       "                                                                                             │           │                                                           │                        │                                                                                                                                                                                          │                           │                                                               │                       │\n",
       "(1, 1): ─────────────────────────────────────────────PhX(1)^0.5──────────────────────────────┼───────────┼───────────────────────────PhX(-0.75)^0.5──────────────────iSwap^0.5────────────────iSwap^0.5────S───Y^0.5─────────────────────Y^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap^0.5───────────────────iSwap^0.5────Z^-0.868───X^0.5─────────Z^-0.75───────────────────┼───────────────────────┼────────────PhX(1)^-0.5────────────────────\n",
       "                                                                                             │           │                                                                                                                                                                                                                                                                                                                                                                           │                       │\n",
       "(1, 2): ──────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────iSwap^0.5───iSwap^0.5───Z^-0.355────────X^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────PhX(0)^-0.5───────────────────────────PhX(0.5)^-0.5────────────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────iSwap^0.5───────────────iSwap^0.5────Z^0.766───────X^0.5───Z^0.75───\n",
       "                                                                                                                                                                                 └─────────────────────┘                                                                                                                                                                  └───────────────────────┘   └───────────────────────┘                                                                  └────────────────────┘</pre>"
      ],
      "text/plain": [
       "                                                                                                                                                                                 ┌─────────────────────┐                                                                                                                                                                  ┌───────────────────────┐   ┌───────────────────────┐                                                                  ┌────────────────────┐\n",
       "(0, 0): ───────────S───iSwap────────────iSwap────────Z───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S────────────iSwap───────────────────iSwap─────────Z───────M('z')───\n",
       "                       │                │                                                                                                                                                                                                                                                                                                                                                                                                                                                         │                       │\n",
       "(0, 1): ───────────────iSwap^0.5────────iSwap^0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────S───S^-1───iSwap────────────────────iSwap────────T───X^0.5───Z^0.75───T────────X^0.5────T^-1──────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.0592)──────────────────iSwap───────────────────────iSwap────────────────────────────────────────────────────────────────────────iSwap^0.5───────────────iSwap^0.5─────S────────────────\n",
       "                                                                                                                                                                     │                        │                                                                                                                                                                                          │                           │\n",
       "(0, 2): ───────────────PhX(-0.25)^0.5─────────────────────────────────────────────Z^-0.145───iSwap───────iSwap───────T───────────────X^0.75───────────S──────────────┼────────────────────────┼─────────────────────────────────X^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5┼───────────────────────────┼───────────────────────────────────────────────PhX(-0.00809)───iSwap───────────────────iSwap────────Z^-0.75───────X^0.5───Z^0.75───\n",
       "                                                                                             │           │                                                           │                        │                                                                                                                                                                                          │                           │                                                               │                       │\n",
       "(1, 0): ────────────────────────────────PhX(0)^0.5───────────────────────────────────────────┼───────────┼───────────PhX(0.75)^0.5───────────────────────────────────┼────────────PhX(0.5)^0.5┼──────────────────────────────────────────Y^-0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────────PhX(0.75)^-0.5┼───────────────────────────────────────────────────────────────┼────────────PhX(0)^-0.5┼───────────────────────────────────────────\n",
       "                                                                                             │           │                                                           │                        │                                                                                                                                                                                          │                           │                                                               │                       │\n",
       "(1, 1): ─────────────────────────────────────────────PhX(1)^0.5──────────────────────────────┼───────────┼───────────────────────────PhX(-0.75)^0.5──────────────────iSwap^0.5────────────────iSwap^0.5────S───Y^0.5─────────────────────Y^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap^0.5───────────────────iSwap^0.5────Z^-0.868───X^0.5─────────Z^-0.75───────────────────┼───────────────────────┼────────────PhX(1)^-0.5────────────────────\n",
       "                                                                                             │           │                                                                                                                                                                                                                                                                                                                                                                           │                       │\n",
       "(1, 2): ──────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────iSwap^0.5───iSwap^0.5───Z^-0.355────────X^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────PhX(0)^-0.5───────────────────────────PhX(0.5)^-0.5────────────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────iSwap^0.5───────────────iSwap^0.5────Z^0.766───────X^0.5───Z^0.75───\n",
       "                                                                                                                                                                                 └─────────────────────┘                                                                                                                                                                  └───────────────────────┘   └───────────────────────┘                                                                  └────────────────────┘"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circuit = cirq.eject_phased_paulis(circuit)\n",
    "circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "M1h-qJsb_5TG"
   },
   "source": [
    "Note that, for example, the back-to-back `cirq.X` gates on the ancilla have been removed from the start of the circuit."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "oKcnKYTE-ms3"
   },
   "source": [
    "You can also use the `cirq.eject_z` optimizer to attempt to push `cirq.Z` gates towards the end of the circuit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "id": "eomQLGiMF9kY"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">                                                                                                                                                                               ┌─────────────────────┐                                                                                                                                                                                                 ┌───────────────────────┐   ┌───────────────────────┐                                                                ┌────────────────────┐\n",
       "(0, 0): ───────────S───iSwap────────────iSwap───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S^-1─────────iSwap───────────────────iSwap───────────────────────────────M(&#x27;z&#x27;)─────\n",
       "                       │                │                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    │                       │\n",
       "(0, 1): ───────────────iSwap^0.5────────iSwap^0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap────────────────────iSwap────────────PhX(-0.25)^0.5─────────────────────────PhX(0.75)^0.5────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.941)───Z──────────────────iSwap───────────────────────iSwap──────────────────────────────────────────────────────────────────────iSwap^0.5───────────────iSwap^0.5─────────S────────────────────────────\n",
       "                                                                                                                                                                   │                        │                                                                                                                                                                                                                         │                           │\n",
       "(0, 2): ───────────────PhX(-0.25)^0.5─────────────────────────────────────────────Z^-0.145───iSwap───────iSwap───────────────────────PhX(-0.25)^0.75───────────────┼────────────────────────┼─────────────────────────────────────PhX(-0.75)^-0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.5)^-0.5┼───────────────────────────┼──────────────────────────────────────PhX(-0.758)───Z^0.75───iSwap───────────────────iSwap──────────────────────────PhX(0.75)^0.5────────────────\n",
       "                                                                                             │           │                                                         │                        │                                                                                                                                                                                                                         │                           │                                                             │                       │\n",
       "(1, 0): ────────────────────────────────PhX(0)^0.5───────────────────────────────────────────┼───────────┼───────────PhX(0.75)^0.5─────────────────────────────────┼────────────PhX(0.5)^0.5┼───────────────────────────────────────────────────────Y^-0.5────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────────PhX(0.75)^-0.5┼─────────────────────────────────────────────────────────────┼────────────PhX(0)^-0.5┼───────────────────────────────────────────────────────────\n",
       "                                                                                             │           │                                                         │                        │                                                                                                                                                                                                                         │                           │                                                             │                       │\n",
       "(1, 1): ─────────────────────────────────────────────PhX(1)^0.5──────────────────────────────┼───────────┼───────────────────────────PhX(-0.75)^0.5────────────────iSwap^0.5────────────────iSwap^0.5────────PhX(0)^0.5─────────────────────────────PhX(0)^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S────────────────────────────────iSwap^0.5───────────────────iSwap^0.5────────PhX(0.868)^0.5───────────────────────────────┼───────────────────────┼────────────PhX(0.618)^-0.5───Z^0.382──────────────────────\n",
       "                                                                                             │           │                                                                                                                                                                                                                                                                                                                                                                                                      │                       │\n",
       "(1, 2): ──────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────iSwap^0.5───iSwap^0.5───────────────────PhX(0.355)^0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.355)^0.5───────────────────PhX(0.355)^-0.5───────────────────────────PhX(0.855)^-0.5─────────────────────────────────────────────────────────────────────────────────────PhX(0.355)^-0.5───────Z^-0.355───────────────iSwap^0.5───────────────iSwap^0.5──────────────────────PhX(-0.766)^0.5───Z^-0.484───\n",
       "                                                                                                                                                                               └─────────────────────┘                                                                                                                                                                                                 └───────────────────────┘   └───────────────────────┘                                                                └────────────────────┘</pre>"
      ],
      "text/plain": [
       "                                                                                                                                                                               ┌─────────────────────┐                                                                                                                                                                                                 ┌───────────────────────┐   ┌───────────────────────┐                                                                ┌────────────────────┐\n",
       "(0, 0): ───────────S───iSwap────────────iSwap───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S^-1─────────iSwap───────────────────iSwap───────────────────────────────M('z')─────\n",
       "                       │                │                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    │                       │\n",
       "(0, 1): ───────────────iSwap^0.5────────iSwap^0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap────────────────────iSwap────────────PhX(-0.25)^0.5─────────────────────────PhX(0.75)^0.5────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.941)───Z──────────────────iSwap───────────────────────iSwap──────────────────────────────────────────────────────────────────────iSwap^0.5───────────────iSwap^0.5─────────S────────────────────────────\n",
       "                                                                                                                                                                   │                        │                                                                                                                                                                                                                         │                           │\n",
       "(0, 2): ───────────────PhX(-0.25)^0.5─────────────────────────────────────────────Z^-0.145───iSwap───────iSwap───────────────────────PhX(-0.25)^0.75───────────────┼────────────────────────┼─────────────────────────────────────PhX(-0.75)^-0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.5)^-0.5┼───────────────────────────┼──────────────────────────────────────PhX(-0.758)───Z^0.75───iSwap───────────────────iSwap──────────────────────────PhX(0.75)^0.5────────────────\n",
       "                                                                                             │           │                                                         │                        │                                                                                                                                                                                                                         │                           │                                                             │                       │\n",
       "(1, 0): ────────────────────────────────PhX(0)^0.5───────────────────────────────────────────┼───────────┼───────────PhX(0.75)^0.5─────────────────────────────────┼────────────PhX(0.5)^0.5┼───────────────────────────────────────────────────────Y^-0.5────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────────PhX(0.75)^-0.5┼─────────────────────────────────────────────────────────────┼────────────PhX(0)^-0.5┼───────────────────────────────────────────────────────────\n",
       "                                                                                             │           │                                                         │                        │                                                                                                                                                                                                                         │                           │                                                             │                       │\n",
       "(1, 1): ─────────────────────────────────────────────PhX(1)^0.5──────────────────────────────┼───────────┼───────────────────────────PhX(-0.75)^0.5────────────────iSwap^0.5────────────────iSwap^0.5────────PhX(0)^0.5─────────────────────────────PhX(0)^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S────────────────────────────────iSwap^0.5───────────────────iSwap^0.5────────PhX(0.868)^0.5───────────────────────────────┼───────────────────────┼────────────PhX(0.618)^-0.5───Z^0.382──────────────────────\n",
       "                                                                                             │           │                                                                                                                                                                                                                                                                                                                                                                                                      │                       │\n",
       "(1, 2): ──────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────iSwap^0.5───iSwap^0.5───────────────────PhX(0.355)^0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.355)^0.5───────────────────PhX(0.355)^-0.5───────────────────────────PhX(0.855)^-0.5─────────────────────────────────────────────────────────────────────────────────────PhX(0.355)^-0.5───────Z^-0.355───────────────iSwap^0.5───────────────iSwap^0.5──────────────────────PhX(-0.766)^0.5───Z^-0.484───\n",
       "                                                                                                                                                                               └─────────────────────┘                                                                                                                                                                                                 └───────────────────────┘   └───────────────────────┘                                                                └────────────────────┘"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circuit = cirq.eject_z(circuit)\n",
    "circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ydUlul4NE_Eu"
   },
   "source": [
    "Note that, for example, the `cirq.Z` gate immediately before the ancilla measurement has been removed."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "824RLaxrVbnH"
   },
   "source": [
    "### Align gates in moments"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "2o8l3r1NGT_T"
   },
   "source": [
    "After optimizing, gates should be aligned into `cirq.Moment`s to satisfy the following criteria:\n",
    "\n",
    "- The fewer moments the better (generally speaking).\n",
    "  - Each moment is a discrete time slice, so fewer moments means shorter circuit execution time.\n",
    "\n",
    "- Moments should consist of gates with similar durations.\n",
    "  - Otherwise some qubits will be idle for part of the moment.\n",
    "  - It's best to align one-qubit gates in their own moment and two-qubit gates in their own moment if possible.\n",
    "\n",
    "- All measurements should be terminal and in a single moment.\n",
    "  - Intermediate measurements are not currently supported, and measurement operation times are roughly two orders of magnitude longer than other gate times (see the above cell which prints out gatesets and gate times).\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "q66K76iTG23G"
   },
   "source": [
    "To align gates into moments and push them as far left as possible, use `cirq.align_left`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "id": "MhFYbG0WGUML"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">                                             ┌─────────────────────┐   ┌────────────────────────┐   ┌────────────────────────┐                                                                                       ┌──────────────────┐   ┌───────────────────────┐\n",
       "(0, 0): ───S────────────────iSwap─────────────iSwap─────────────────────S^-1─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap──────────────────────iSwap─────────────M(&#x27;z&#x27;)─────\n",
       "                            │                 │                                                                                                                                                                                              │                          │\n",
       "(0, 1): ────────────────────iSwap^0.5─────────iSwap^0.5──────────────────────────iSwap──────────────────────────────iSwap────────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap────────iSwap──────────────────iSwap^0.5──────────────────iSwap^0.5─────────S──────────\n",
       "                                                                                 │                                  │                                                                                    │            │\n",
       "(0, 2): ───PhX(-0.25)^0.5───Z^-0.145──────────iSwap─────────────────────iSwap────┼───────────────────PhX(-0.25)^0.75┼────────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼────────────┼────────iSwap───────────────────────iSwap────────PhX(0.75)^0.5────────────────\n",
       "                                              │                         │        │                                  │                                                                                    │            │        │                           │\n",
       "(1, 0): ───PhX(0)^0.5───────PhX(0.75)^0.5─────┼────────PhX(0.5)^0.5─────┼────────┼────────Y^-0.5─────PhX(0.75)^-0.5─┼────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────┼────────────┼────────┼───────────────────────────┼─────────────────────────────────────────\n",
       "                                              │                         │        │                                  │                                                                                    │            │        │                           │\n",
       "(1, 1): ───PhX(1)^0.5───────PhX(-0.75)^0.5────┼─────────────────────────┼────────iSwap^0.5──────────────────────────iSwap^0.5────PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5────iSwap^0.5┼─────────────PhX(0.868)^0.5┼────────────PhX(0.618)^-0.5───Z^0.382────\n",
       "                                              │                         │                                                                                                                                                      │                           │\n",
       "(1, 2): ───PhX(0.75)^0.5──────────────────────iSwap^0.5─────────────────iSwap^0.5────────────────────PhX(0.355)^0.5──────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───Z^-0.355──────────────iSwap^0.5───────────────────iSwap^0.5────PhX(-0.766)^0.5───Z^-0.484───\n",
       "                                             └─────────────────────┘   └────────────────────────┘   └────────────────────────┘                                                                                       └──────────────────┘   └───────────────────────┘</pre>"
      ],
      "text/plain": [
       "                                             ┌─────────────────────┐   ┌────────────────────────┐   ┌────────────────────────┐                                                                                       ┌──────────────────┐   ┌───────────────────────┐\n",
       "(0, 0): ───S────────────────iSwap─────────────iSwap─────────────────────S^-1─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap──────────────────────iSwap─────────────M('z')─────\n",
       "                            │                 │                                                                                                                                                                                              │                          │\n",
       "(0, 1): ────────────────────iSwap^0.5─────────iSwap^0.5──────────────────────────iSwap──────────────────────────────iSwap────────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap────────iSwap──────────────────iSwap^0.5──────────────────iSwap^0.5─────────S──────────\n",
       "                                                                                 │                                  │                                                                                    │            │\n",
       "(0, 2): ───PhX(-0.25)^0.5───Z^-0.145──────────iSwap─────────────────────iSwap────┼───────────────────PhX(-0.25)^0.75┼────────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼────────────┼────────iSwap───────────────────────iSwap────────PhX(0.75)^0.5────────────────\n",
       "                                              │                         │        │                                  │                                                                                    │            │        │                           │\n",
       "(1, 0): ───PhX(0)^0.5───────PhX(0.75)^0.5─────┼────────PhX(0.5)^0.5─────┼────────┼────────Y^-0.5─────PhX(0.75)^-0.5─┼────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────┼────────────┼────────┼───────────────────────────┼─────────────────────────────────────────\n",
       "                                              │                         │        │                                  │                                                                                    │            │        │                           │\n",
       "(1, 1): ───PhX(1)^0.5───────PhX(-0.75)^0.5────┼─────────────────────────┼────────iSwap^0.5──────────────────────────iSwap^0.5────PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5────iSwap^0.5┼─────────────PhX(0.868)^0.5┼────────────PhX(0.618)^-0.5───Z^0.382────\n",
       "                                              │                         │                                                                                                                                                      │                           │\n",
       "(1, 2): ───PhX(0.75)^0.5──────────────────────iSwap^0.5─────────────────iSwap^0.5────────────────────PhX(0.355)^0.5──────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───Z^-0.355──────────────iSwap^0.5───────────────────iSwap^0.5────PhX(-0.766)^0.5───Z^-0.484───\n",
       "                                             └─────────────────────┘   └────────────────────────┘   └────────────────────────┘                                                                                       └──────────────────┘   └───────────────────────┘"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "left_aligned_circuit = cirq.align_left(circuit)\n",
    "left_aligned_circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "J537zBXPHny4"
   },
   "source": [
    "Note: Optimizers can cause terminal measurements to become misaligned, but this can be fixed with `cirq.synchronize_terminal_measurements` as discussed below."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "dectZpWqHMFL"
   },
   "source": [
    "Note how many fewer moments this aligned circuit has."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "id": "o-MDeT-wHa97"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Original circuit has 54 moments.\n",
      "Aligned circuit has 14 moments.\n"
     ]
    }
   ],
   "source": [
    "print(f\"Original circuit has {len(circuit)} moments.\")\n",
    "print(f\"Aligned circuit has {len(left_aligned_circuit)} moments.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "v7VhDhlOHQuQ"
   },
   "source": [
    "You can also align gates and push them to the right with `cirq.align_right`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "id": "NOcRIJacGihn"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">                                            ┌───────────────────────┐   ┌──────────────────┐                                                                                            ┌──────────────────────┐   ┌──────────────────────────────┐   ┌───────────────────────┐\n",
       "(0, 0): ───S────────────────iSwap────────────iSwap──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S^-1───────────────────────────────iSwap──────────────────────iSwap─────────────M(&#x27;z&#x27;)──────────\n",
       "                            │                │                                                                                                                                                                                                         │                          │\n",
       "(0, 1): ────────────────────iSwap^0.5────────iSwap^0.5───────────────────iSwap─────────────────iSwap────────────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z───────────────────────────────iSwap──────────────────iSwap─────────────────────iSwap^0.5──────────────────iSwap^0.5─────────S───────────────\n",
       "                                                                         │                     │                                                                                                      │                      │\n",
       "(0, 2): ───PhX(-0.25)^0.5───Z^-0.145───────────────────────iSwap─────────┼────────iSwap────────┼────────────────PhX(-0.25)^0.75───PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)────────Z^0.75───────┼─────────────iSwap────┼─────────────────────────iSwap────────────────────────────────────────PhX(0.75)^0.5───\n",
       "                                                           │             │        │            │                                                                                                      │             │        │                         │\n",
       "(1, 0): ───────────────────────────────────────────────────┼─────────────┼────────┼────────────┼──────────────────────────────────────────────────────────────────────PhX(0)^0.5─────────PhX(0.75)^0.5┼─────────────┼────────┼────────PhX(0.5)^0.5─────┼────────Y^-0.5────────────PhX(0.75)^-0.5────PhX(0)^-0.5─────\n",
       "                                                           │             │        │            │                                                                                                      │             │        │                         │\n",
       "(1, 1): ────────────────────PhX(1)^0.5───────PhX(-0.75)^0.5┼─────────────iSwap^0.5┼────────────iSwap^0.5──────────────────────────PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────iSwap^0.5─────┼────────iSwap^0.5─────────────────┼────────PhX(0.868)^0.5────PhX(0.618)^-0.5───Z^0.382─────────\n",
       "                                                           │                      │                                                                                                                                 │                                  │\n",
       "(1, 2): ────────────────────PhX(0.75)^0.5──────────────────iSwap^0.5──────────────iSwap^0.5────PhX(0.355)^0.5───PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5────Z^-0.355───────────────────iSwap^0.5──────────────────────────iSwap^0.5──────────────────PhX(-0.766)^0.5───Z^-0.484────────\n",
       "                                            └───────────────────────┘   └──────────────────┘                                                                                            └──────────────────────┘   └──────────────────────────────┘   └───────────────────────┘</pre>"
      ],
      "text/plain": [
       "                                            ┌───────────────────────┐   ┌──────────────────┐                                                                                            ┌──────────────────────┐   ┌──────────────────────────────┐   ┌───────────────────────┐\n",
       "(0, 0): ───S────────────────iSwap────────────iSwap──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S^-1───────────────────────────────iSwap──────────────────────iSwap─────────────M('z')──────────\n",
       "                            │                │                                                                                                                                                                                                         │                          │\n",
       "(0, 1): ────────────────────iSwap^0.5────────iSwap^0.5───────────────────iSwap─────────────────iSwap────────────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z───────────────────────────────iSwap──────────────────iSwap─────────────────────iSwap^0.5──────────────────iSwap^0.5─────────S───────────────\n",
       "                                                                         │                     │                                                                                                      │                      │\n",
       "(0, 2): ───PhX(-0.25)^0.5───Z^-0.145───────────────────────iSwap─────────┼────────iSwap────────┼────────────────PhX(-0.25)^0.75───PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)────────Z^0.75───────┼─────────────iSwap────┼─────────────────────────iSwap────────────────────────────────────────PhX(0.75)^0.5───\n",
       "                                                           │             │        │            │                                                                                                      │             │        │                         │\n",
       "(1, 0): ───────────────────────────────────────────────────┼─────────────┼────────┼────────────┼──────────────────────────────────────────────────────────────────────PhX(0)^0.5─────────PhX(0.75)^0.5┼─────────────┼────────┼────────PhX(0.5)^0.5─────┼────────Y^-0.5────────────PhX(0.75)^-0.5────PhX(0)^-0.5─────\n",
       "                                                           │             │        │            │                                                                                                      │             │        │                         │\n",
       "(1, 1): ────────────────────PhX(1)^0.5───────PhX(-0.75)^0.5┼─────────────iSwap^0.5┼────────────iSwap^0.5──────────────────────────PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────iSwap^0.5─────┼────────iSwap^0.5─────────────────┼────────PhX(0.868)^0.5────PhX(0.618)^-0.5───Z^0.382─────────\n",
       "                                                           │                      │                                                                                                                                 │                                  │\n",
       "(1, 2): ────────────────────PhX(0.75)^0.5──────────────────iSwap^0.5──────────────iSwap^0.5────PhX(0.355)^0.5───PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5────Z^-0.355───────────────────iSwap^0.5──────────────────────────iSwap^0.5──────────────────PhX(-0.766)^0.5───Z^-0.484────────\n",
       "                                            └───────────────────────┘   └──────────────────┘                                                                                            └──────────────────────┘   └──────────────────────────────┘   └───────────────────────┘"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "right_aligned_circuit = cirq.align_right(circuit)\n",
    "right_aligned_circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "R9SbfOfPVdMv"
   },
   "source": [
    "Also, you can use `cirq.stratified_circuit` to align operations into similar categories. For example, you can align single-qubit and two-qubit operations in separate moments as follows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "id": "7LRQ3WooVd1Z"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">                                                                                    ┌──────────────────┐                                                                                                                                ┌──────────────────┐\n",
       "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────────iSwap───────M(&#x27;z&#x27;)─────\n",
       "                            │                            │                                                                                                                                                                                                                      │                             │\n",
       "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap───────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S──────────\n",
       "                                                                                              │                              │                                                                                   │                       │\n",
       "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼───────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                       │        │                             │\n",
       "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼───────────────────────┼────────┼─────────────────────────────┼────────────────────────────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                       │        │                             │\n",
       "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5───────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382────\n",
       "                                                         │                           │                                                                                                                                                            │                             │\n",
       "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355─────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484───\n",
       "                                                                                    └──────────────────┘                                                                                                                                └──────────────────┘</pre>"
      ],
      "text/plain": [
       "                                                                                    ┌──────────────────┐                                                                                                                                ┌──────────────────┐\n",
       "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────────iSwap───────M('z')─────\n",
       "                            │                            │                                                                                                                                                                                                                      │                             │\n",
       "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap───────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S──────────\n",
       "                                                                                              │                              │                                                                                   │                       │\n",
       "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼───────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                       │        │                             │\n",
       "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼───────────────────────┼────────┼─────────────────────────────┼────────────────────────────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                       │        │                             │\n",
       "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5───────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382────\n",
       "                                                         │                           │                                                                                                                                                            │                             │\n",
       "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355─────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484───\n",
       "                                                                                    └──────────────────┘                                                                                                                                └──────────────────┘"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circuit = cirq.stratified_circuit(\n",
    "    circuit, categories=[lambda op: len(op.qubits) == 1, lambda op: len(op.qubits) == 2]\n",
    ")\n",
    "circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Z7U3Bu37Q0Hz"
   },
   "source": [
    "Note that each moment now only contains single-qubit gates or two-qubit gates."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "V1dZEX6uHIhD"
   },
   "source": [
    "#### Drop moments"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "yFRC4G8hI8W-"
   },
   "source": [
    "To drop moments that have a tiny effect or moments that are empty, you can use the following optimizers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "id": "lUoGe6sAHItP"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">                                                                                    ┌──────────────────┐                                                                                                                                ┌──────────────────┐\n",
       "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────────iSwap───────M(&#x27;z&#x27;)─────\n",
       "                            │                            │                                                                                                                                                                                                                      │                             │\n",
       "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap───────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S──────────\n",
       "                                                                                              │                              │                                                                                   │                       │\n",
       "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼───────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                       │        │                             │\n",
       "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼───────────────────────┼────────┼─────────────────────────────┼────────────────────────────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                       │        │                             │\n",
       "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5───────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382────\n",
       "                                                         │                           │                                                                                                                                                            │                             │\n",
       "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355─────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484───\n",
       "                                                                                    └──────────────────┘                                                                                                                                └──────────────────┘</pre>"
      ],
      "text/plain": [
       "                                                                                    ┌──────────────────┐                                                                                                                                ┌──────────────────┐\n",
       "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────────iSwap───────M('z')─────\n",
       "                            │                            │                                                                                                                                                                                                                      │                             │\n",
       "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap───────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S──────────\n",
       "                                                                                              │                              │                                                                                   │                       │\n",
       "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼───────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                       │        │                             │\n",
       "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼───────────────────────┼────────┼─────────────────────────────┼────────────────────────────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                       │        │                             │\n",
       "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5───────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382────\n",
       "                                                         │                           │                                                                                                                                                            │                             │\n",
       "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355─────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484───\n",
       "                                                                                    └──────────────────┘                                                                                                                                └──────────────────┘"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circuit = cirq.drop_negligible_operations(circuit)\n",
    "circuit = cirq.drop_empty_moments(circuit)\n",
    "circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "YdXaElSeIk3K"
   },
   "source": [
    "#### Synchronize terminal measurements"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "q0J0zRqjKKhP"
   },
   "source": [
    "You can use the `cirq.synchronize_terminal_measurements` to move all measurements to the final moment if it can accommodate them (without overlapping with other operations)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "id": "0ZrpvUJyHzNh"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">                                                                                    ┌──────────────────┐                                                                                                                                ┌──────────────────┐\n",
       "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────────iSwap──────────────────M(&#x27;z&#x27;)───\n",
       "                            │                            │                                                                                                                                                                                                                      │                             │\n",
       "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap───────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S───────────────────\n",
       "                                                                                              │                              │                                                                                   │                       │\n",
       "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼───────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5─────────────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                       │        │                             │\n",
       "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼───────────────────────┼────────┼─────────────────────────────┼─────────────────────────────────────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                       │        │                             │\n",
       "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5───────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382─────────────\n",
       "                                                         │                           │                                                                                                                                                            │                             │\n",
       "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355─────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484────────────\n",
       "                                                                                    └──────────────────┘                                                                                                                                └──────────────────┘</pre>"
      ],
      "text/plain": [
       "                                                                                    ┌──────────────────┐                                                                                                                                ┌──────────────────┐\n",
       "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────────iSwap──────────────────M('z')───\n",
       "                            │                            │                                                                                                                                                                                                                      │                             │\n",
       "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap───────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S───────────────────\n",
       "                                                                                              │                              │                                                                                   │                       │\n",
       "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼───────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5─────────────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                       │        │                             │\n",
       "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼───────────────────────┼────────┼─────────────────────────────┼─────────────────────────────────────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                       │        │                             │\n",
       "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5───────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382─────────────\n",
       "                                                         │                           │                                                                                                                                                            │                             │\n",
       "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355─────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484────────────\n",
       "                                                                                    └──────────────────┘                                                                                                                                └──────────────────┘"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circuit = cirq.synchronize_terminal_measurements(circuit)\n",
    "circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "b5i41UXNfree"
   },
   "source": [
    "## Adding spin echoes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "1VoTQNIzfupZ"
   },
   "source": [
    "[Dynamical decoupling](https://arxiv.org/abs/quant-ph/9803057) applies a series of spin echoes to otherwise idle qubits to reduce decoherent effects. As mentioned above, spin echoes were used as an effective error mitigation technique in [Information Scrambling in Computationally Complex Quantum Circuits](https://arxiv.org/abs/2101.08870), and the performance of any circuit with idle qubits can potentially be improved by adding spin echoes."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "rvo9HcLoKw4w"
   },
   "source": [
    "The following codeblock shows how to insert spin echoes on the ancilla qubit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "id": "gyKYbFtt8Dvd"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">                                                                                    ┌──────────────────┐                                                                                                                                 ┌──────────────────┐\n",
       "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1──────────────────────────────────PhX(0)────────────────────────PhX(0)────────────PhX(1)────────────PhX(1)────────────PhX(-0.5)─────────────────────PhX(-0.5)───────────────────────────────────────────iSwap─────────────────────────iSwap───────M(&#x27;z&#x27;)─────\n",
       "                            │                            │                                                                                                                                                                                                                       │                             │\n",
       "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap────────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S──────────\n",
       "                                                                                              │                              │                                                                                   │                        │\n",
       "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼────────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                        │        │                             │\n",
       "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼────────────────────────┼────────┼─────────────────────────────┼────────────────────────────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                        │        │                             │\n",
       "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5────────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382────\n",
       "                                                         │                           │                                                                                                                                                             │                             │\n",
       "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355──────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484───\n",
       "                                                                                    └──────────────────┘                                                                                                                                 └──────────────────┘</pre>"
      ],
      "text/plain": [
       "                                                                                    ┌──────────────────┐                                                                                                                                 ┌──────────────────┐\n",
       "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1──────────────────────────────────PhX(0)────────────────────────PhX(0)────────────PhX(1)────────────PhX(1)────────────PhX(-0.5)─────────────────────PhX(-0.5)───────────────────────────────────────────iSwap─────────────────────────iSwap───────M('z')─────\n",
       "                            │                            │                                                                                                                                                                                                                       │                             │\n",
       "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap────────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S──────────\n",
       "                                                                                              │                              │                                                                                   │                        │\n",
       "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼────────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                        │        │                             │\n",
       "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼────────────────────────┼────────┼─────────────────────────────┼────────────────────────────────────────────────────\n",
       "                                                         │                           │        │                              │                                                                                   │                        │        │                             │\n",
       "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5────────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382────\n",
       "                                                         │                           │                                                                                                                                                             │                             │\n",
       "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355──────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484───\n",
       "                                                                                    └──────────────────┘                                                                                                                                 └──────────────────┘"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Gates for spin echoes. Note that these gates are self-inverse.\n",
    "pi_pulses = [cirq.PhasedXPowGate(phase_exponent=p, exponent=1.0) for p in (-0.5, 0.0, 0.5, 1.0)]\n",
    "\n",
    "# Generate spin echoes on ancilla.\n",
    "num_echoes = 3\n",
    "random_state = np.random.RandomState(1)\n",
    "\n",
    "spin_echo = []\n",
    "for _ in range(num_echoes):\n",
    "    op = random_state.choice(pi_pulses).on(qubits[0])\n",
    "    spin_echo += [op, cirq.inverse(op)]\n",
    "\n",
    "# Insert spin echo operations to circuit.\n",
    "optimized_circuit_with_spin_echoes = circuit.copy()\n",
    "optimized_circuit_with_spin_echoes.insert(5, spin_echo)\n",
    "\n",
    "# Align single-qubit spin echo gates into other moments of single-qubit gates.\n",
    "optimized_circuit_with_spin_echoes = cirq.stratified_circuit(\n",
    "    optimized_circuit_with_spin_echoes,\n",
    "    categories=[lambda op: len(op.qubits) == 1, lambda op: len(op.qubits) == 2],\n",
    ")\n",
    "optimized_circuit_with_spin_echoes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "fshsOLq_05zV"
   },
   "source": [
    "The ancilla now has spin echoes between the two-qubit gates at the start/end of the circuit instead of remaining idle."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "nDOcuX94054O"
   },
   "source": [
    "## Benchmark"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "pclRv5YIMRM2"
   },
   "source": [
    "Now that we have discussed how to remove uncessary gates, align gates, and insert spin echoes, we run an experiment to benchmark the results. First we get a line of qubits, list of cycle values (one circuit per cycle value), and set other experimental parameters."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "id": "FGFb2YN43g9D"
   },
   "outputs": [],
   "source": [
    "\"\"\"Set experiment parameters.\"\"\"\n",
    "\n",
    "qubits = cg.line_on_device(device_sampler.device, length=7)\n",
    "cycle_values = range(0, 100 + 1, 4)\n",
    "nreps = 20_000\n",
    "seed = 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "B4Pbu2F9MTFg"
   },
   "source": [
    "The `create_benchmark_circuit` defined at the start of this tutorial has options to optimize the circuit and insert spin echoes on the ancilla as we have discussed above. Without any optimization or spin echoes, an example circuit looks like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "id": "qP8CWEPj_QkS"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Unoptimized circuit (47 moments):\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            ┌─────────────────────────┐\n",
       "(3, 2): ───X───iSwap────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap────────────────────────────────────────────────────────────────────────M(&#x27;z&#x27;)───\n",
       "               │                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            │\n",
       "(4, 1): ───────┼───────────────────────────PhX(-0.25)^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.25)^0.5─────────────────────────────────────────────────────────────────iSwap───────────────────────────────────PhX(0)^0.5──────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────────────iSwap───────────────────────────────────────PhX(0.25)^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.25)^-0.5┼─────────────────────────────────────────────────────────────────────────────────────\n",
       "               │                                                                                                                                                                                                                              │                                                                                                                                                                                                                   │                                                                                                                                                                                         │\n",
       "(4, 2): ───────iSwap^0.5───PhX(0.25)^0.5───────────────────────────────────────────────────────────────────────────────iSwap───────────────────PhX(-0.25)^0.5─────────────────────────────────────────────────────────────────────────────────┼───────────────────────PhX(0.25)^0.5──────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5───────────────────────────────────────────────────────────────────────────────────┼─────────────────────────PhX(-0.25)^-0.5──────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────PhX(0.25)^-0.5───────────────────iSwap^-0.5────────────────────────────────────────────────────────────────────────────\n",
       "                                                                                                                       │                                                                                                                      │                                                                                                                                                                                                                   │                                                                                                                              │\n",
       "(5, 1): ────────────────────────────────────────────────────PhX(0)^0.5─────────────────────────────────────────────────┼───────────iSwap────────────────────────────────────────PhX(0.75)^0.5─────────────────────────────────────────────────iSwap^0.5────────────────────────────────────────────PhX(0.5)^0.5─────────────────────────────────────────────────────────────────────────────────PhX(0.5)^-0.5─────────────────────────────────────────────────────iSwap^-0.5───────────────────────────────────────────────────PhX(0.75)^-0.5────────────────────────────────────────────────────┼────────────iSwap───────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────\n",
       "                                                                                                                       │           │                                                                                                                                                                                                                                                                                                                                                                                                                                                             │            │\n",
       "(5, 2): ──────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.75)^0.5───iSwap^0.5───┼──────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5───────────────iSwap──────────────────────────────────────────────────────────────────────────────────PhX(0.25)^0.5───────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5────────────────iSwap────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^-0.5───iSwap^-0.5───┼────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.75)^-0.5────────────\n",
       "                                                                                                                                   │                                                                                                                      │                                                                                                                                                                                                                    │                                                                                                                              │\n",
       "(6, 1): ─────────────────────────────────────────────────────────────────PhX(1)^0.5────────────────────────────────────────────────iSwap^0.5────────────────────────────────────────────────────PhX(-0.75)^0.5────────────────────────────────────────────┼───────────────────────────────────────────────────────PhX(-0.5)^0.5─────────────────────────────────────────────────────────────────────────────────PhX(-0.5)^-0.5─────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────PhX(-0.75)^-0.5───────────────────────────────────────────────iSwap^-0.5────────────────────────────────────────────────────────────────PhX(1)^-0.5───────────────────────────────────────────────\n",
       "                                                                                                                                                                                                                                                          │                                                                                                                                                                                                                    │\n",
       "(6, 2): ──────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────────────────iSwap^0.5───────────────────────────────────────────────────────────────PhX(0.5)^0.5───────────────────────────────────────────────────────────────────────────────────PhX(0.5)^-0.5─────────────────────────────────iSwap^-0.5─────────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^-0.5──────────────────────────────\n",
       "                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            └─────────────────────────┘</pre>"
      ],
      "text/plain": [
       "                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            ┌─────────────────────────┐\n",
       "(3, 2): ───X───iSwap────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap────────────────────────────────────────────────────────────────────────M('z')───\n",
       "               │                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            │\n",
       "(4, 1): ───────┼───────────────────────────PhX(-0.25)^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.25)^0.5─────────────────────────────────────────────────────────────────iSwap───────────────────────────────────PhX(0)^0.5──────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────────────iSwap───────────────────────────────────────PhX(0.25)^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.25)^-0.5┼─────────────────────────────────────────────────────────────────────────────────────\n",
       "               │                                                                                                                                                                                                                              │                                                                                                                                                                                                                   │                                                                                                                                                                                         │\n",
       "(4, 2): ───────iSwap^0.5───PhX(0.25)^0.5───────────────────────────────────────────────────────────────────────────────iSwap───────────────────PhX(-0.25)^0.5─────────────────────────────────────────────────────────────────────────────────┼───────────────────────PhX(0.25)^0.5──────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5───────────────────────────────────────────────────────────────────────────────────┼─────────────────────────PhX(-0.25)^-0.5──────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────PhX(0.25)^-0.5───────────────────iSwap^-0.5────────────────────────────────────────────────────────────────────────────\n",
       "                                                                                                                       │                                                                                                                      │                                                                                                                                                                                                                   │                                                                                                                              │\n",
       "(5, 1): ────────────────────────────────────────────────────PhX(0)^0.5─────────────────────────────────────────────────┼───────────iSwap────────────────────────────────────────PhX(0.75)^0.5─────────────────────────────────────────────────iSwap^0.5────────────────────────────────────────────PhX(0.5)^0.5─────────────────────────────────────────────────────────────────────────────────PhX(0.5)^-0.5─────────────────────────────────────────────────────iSwap^-0.5───────────────────────────────────────────────────PhX(0.75)^-0.5────────────────────────────────────────────────────┼────────────iSwap───────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────\n",
       "                                                                                                                       │           │                                                                                                                                                                                                                                                                                                                                                                                                                                                             │            │\n",
       "(5, 2): ──────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.75)^0.5───iSwap^0.5───┼──────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5───────────────iSwap──────────────────────────────────────────────────────────────────────────────────PhX(0.25)^0.5───────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5────────────────iSwap────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^-0.5───iSwap^-0.5───┼────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.75)^-0.5────────────\n",
       "                                                                                                                                   │                                                                                                                      │                                                                                                                                                                                                                    │                                                                                                                              │\n",
       "(6, 1): ─────────────────────────────────────────────────────────────────PhX(1)^0.5────────────────────────────────────────────────iSwap^0.5────────────────────────────────────────────────────PhX(-0.75)^0.5────────────────────────────────────────────┼───────────────────────────────────────────────────────PhX(-0.5)^0.5─────────────────────────────────────────────────────────────────────────────────PhX(-0.5)^-0.5─────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────PhX(-0.75)^-0.5───────────────────────────────────────────────iSwap^-0.5────────────────────────────────────────────────────────────────PhX(1)^-0.5───────────────────────────────────────────────\n",
       "                                                                                                                                                                                                                                                          │                                                                                                                                                                                                                    │\n",
       "(6, 2): ──────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────────────────iSwap^0.5───────────────────────────────────────────────────────────────PhX(0.5)^0.5───────────────────────────────────────────────────────────────────────────────────PhX(0.5)^-0.5─────────────────────────────────iSwap^-0.5─────────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^-0.5──────────────────────────────\n",
       "                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            └─────────────────────────┘"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circuit = create_benchmark_circuit(qubits, cycles=2, seed=1)\n",
    "print(f\"Unoptimized circuit ({len(circuit)} moments):\\n\")\n",
    "circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "omR0mlzl_kGN"
   },
   "source": [
    "After removing unnecessary gates (optimization) and aligning gates, the same circuit looks like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "id": "f6sj5umf_W4J"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Circuit with optimization + alignment (15 moments):\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">                                                                                                                                                  ┌────────────────────────────┐                                     ┌─────────────────────────┐\n",
       "(3, 2): ───PhX(0)───iSwap────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────Z────────────────iSwap──────────────────────────────────────────M(&#x27;z&#x27;)───\n",
       "                    │                                                                                                                                                                                                 │\n",
       "(4, 1): ────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.25)^0.5────PhX(0.25)^0.5────┼──────────PhX(-0.75)^0.5────PhX(-0.25)^-0.5────────────\n",
       "                    │                                                                                                                                                                                                 │\n",
       "(4, 2): ────────────iSwap^0.5───PhX(0.25)^0.5────iSwap───────PhX(-0.25)^0.5───PhX(0.25)^0.5───PhX(0.25)^-0.5───PhX(-0.25)^-0.5───Z─────────────────iSwap───────────────────────────PhX(0.25)^0.5─────Z────────────────iSwap^0.5───────────────────────────────────────────────\n",
       "                                                 │                                                                                                 │\n",
       "(5, 1): ─────────────────────────────────────────┼────────────────────────────PhX(0)^0.5──────iSwap──────────────────────────────PhX(0.75)^0.5─────┼─────────────PhX(-0.25)^0.5────Z─────────────────iSwap────────────PhX(1)^-0.5──────────────────Z──────────────────────────\n",
       "                                                 │                                            │                                                    │                                                 │\n",
       "(5, 2): ────────────────────────PhX(-0.75)^0.5───iSwap^0.5────────────────────────────────────┼────────────────PhX(0.75)^0.5─────PhX(-0.25)^0.5────iSwap^0.5─────────────────────────────────────────┼─────────────────────────────────────────────PhX(-0.75)^-0.5────────────\n",
       "                                                                                              │                                                                                                      │\n",
       "(6, 1): ──────────────────────────────────────────────────────────────────────PhX(1)^0.5──────iSwap^0.5────────PhX(-0.75)^0.5────PhX(-0.5)^0.5─────PhX(-0.5)^-0.5──────────────────PhX(-0.75)^-0.5───iSwap^0.5─────────────────────────────────────X^0.5──────────────────────\n",
       "\n",
       "(6, 2): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5─────PhX(0)^0.5───────X^-0.5───────────────────────PhX(0.75)^-0.5─────────────\n",
       "                                                                                                                                                  └────────────────────────────┘                                     └─────────────────────────┘</pre>"
      ],
      "text/plain": [
       "                                                                                                                                                  ┌────────────────────────────┐                                     ┌─────────────────────────┐\n",
       "(3, 2): ───PhX(0)───iSwap────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────Z────────────────iSwap──────────────────────────────────────────M('z')───\n",
       "                    │                                                                                                                                                                                                 │\n",
       "(4, 1): ────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.25)^0.5────PhX(0.25)^0.5────┼──────────PhX(-0.75)^0.5────PhX(-0.25)^-0.5────────────\n",
       "                    │                                                                                                                                                                                                 │\n",
       "(4, 2): ────────────iSwap^0.5───PhX(0.25)^0.5────iSwap───────PhX(-0.25)^0.5───PhX(0.25)^0.5───PhX(0.25)^-0.5───PhX(-0.25)^-0.5───Z─────────────────iSwap───────────────────────────PhX(0.25)^0.5─────Z────────────────iSwap^0.5───────────────────────────────────────────────\n",
       "                                                 │                                                                                                 │\n",
       "(5, 1): ─────────────────────────────────────────┼────────────────────────────PhX(0)^0.5──────iSwap──────────────────────────────PhX(0.75)^0.5─────┼─────────────PhX(-0.25)^0.5────Z─────────────────iSwap────────────PhX(1)^-0.5──────────────────Z──────────────────────────\n",
       "                                                 │                                            │                                                    │                                                 │\n",
       "(5, 2): ────────────────────────PhX(-0.75)^0.5───iSwap^0.5────────────────────────────────────┼────────────────PhX(0.75)^0.5─────PhX(-0.25)^0.5────iSwap^0.5─────────────────────────────────────────┼─────────────────────────────────────────────PhX(-0.75)^-0.5────────────\n",
       "                                                                                              │                                                                                                      │\n",
       "(6, 1): ──────────────────────────────────────────────────────────────────────PhX(1)^0.5──────iSwap^0.5────────PhX(-0.75)^0.5────PhX(-0.5)^0.5─────PhX(-0.5)^-0.5──────────────────PhX(-0.75)^-0.5───iSwap^0.5─────────────────────────────────────X^0.5──────────────────────\n",
       "\n",
       "(6, 2): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5─────PhX(0)^0.5───────X^-0.5───────────────────────PhX(0.75)^-0.5─────────────\n",
       "                                                                                                                                                  └────────────────────────────┘                                     └─────────────────────────┘"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "optimized_circuit = create_benchmark_circuit(\n",
    "    qubits, cycles=2, seed=1, with_optimization=True, with_alignment=True\n",
    ")\n",
    "print(f\"Circuit with optimization + alignment ({len(optimized_circuit)} moments):\\n\")\n",
    "optimized_circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "9G4KFlAO_k5d"
   },
   "source": [
    "And with optimization + alginment + spin echoes on the ancilla, the same circuit looks like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "id": "g52V6Y4b0A7f"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Circuit with optimization + alignment + spin echoes (15 moments):\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">                                                                                                                                                  ┌────────────────────────────┐                                     ┌─────────────────────────┐\n",
       "(3, 2): ───PhX(0)───iSwap────────────────────────PhX(0)──────PhX(0)───────────PhX(1)──────────PhX(1)───────────PhX(-0.5)─────────PhX(-0.5)─────────PhX(-0.5)───────────────────────PhX(-0.5)─────────Z────────────────iSwap──────────────────────────────────────────M(&#x27;z&#x27;)───\n",
       "                    │                                                                                                                                                                                                 │\n",
       "(4, 1): ────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.25)^0.5────PhX(0.25)^0.5────┼──────────PhX(-0.75)^0.5────PhX(-0.25)^-0.5────────────\n",
       "                    │                                                                                                                                                                                                 │\n",
       "(4, 2): ────────────iSwap^0.5───PhX(0.25)^0.5────iSwap───────PhX(-0.25)^0.5───PhX(0.25)^0.5───PhX(0.25)^-0.5───PhX(-0.25)^-0.5───Z─────────────────iSwap───────────────────────────PhX(0.25)^0.5─────Z────────────────iSwap^0.5───────────────────────────────────────────────\n",
       "                                                 │                                                                                                 │\n",
       "(5, 1): ─────────────────────────────────────────┼────────────────────────────PhX(0)^0.5──────iSwap──────────────────────────────PhX(0.75)^0.5─────┼─────────────PhX(-0.25)^0.5────Z─────────────────iSwap────────────PhX(1)^-0.5──────────────────Z──────────────────────────\n",
       "                                                 │                                            │                                                    │                                                 │\n",
       "(5, 2): ────────────────────────PhX(-0.75)^0.5───iSwap^0.5────────────────────────────────────┼────────────────PhX(0.75)^0.5─────PhX(-0.25)^0.5────iSwap^0.5─────────────────────────────────────────┼─────────────────────────────────────────────PhX(-0.75)^-0.5────────────\n",
       "                                                                                              │                                                                                                      │\n",
       "(6, 1): ──────────────────────────────────────────────────────────────────────PhX(1)^0.5──────iSwap^0.5────────PhX(-0.75)^0.5────PhX(-0.5)^0.5─────PhX(-0.5)^-0.5──────────────────PhX(-0.75)^-0.5───iSwap^0.5─────────────────────────────────────X^0.5──────────────────────\n",
       "\n",
       "(6, 2): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5─────PhX(0)^0.5───────X^-0.5───────────────────────PhX(0.75)^-0.5─────────────\n",
       "                                                                                                                                                  └────────────────────────────┘                                     └─────────────────────────┘</pre>"
      ],
      "text/plain": [
       "                                                                                                                                                  ┌────────────────────────────┐                                     ┌─────────────────────────┐\n",
       "(3, 2): ───PhX(0)───iSwap────────────────────────PhX(0)──────PhX(0)───────────PhX(1)──────────PhX(1)───────────PhX(-0.5)─────────PhX(-0.5)─────────PhX(-0.5)───────────────────────PhX(-0.5)─────────Z────────────────iSwap──────────────────────────────────────────M('z')───\n",
       "                    │                                                                                                                                                                                                 │\n",
       "(4, 1): ────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.25)^0.5────PhX(0.25)^0.5────┼──────────PhX(-0.75)^0.5────PhX(-0.25)^-0.5────────────\n",
       "                    │                                                                                                                                                                                                 │\n",
       "(4, 2): ────────────iSwap^0.5───PhX(0.25)^0.5────iSwap───────PhX(-0.25)^0.5───PhX(0.25)^0.5───PhX(0.25)^-0.5───PhX(-0.25)^-0.5───Z─────────────────iSwap───────────────────────────PhX(0.25)^0.5─────Z────────────────iSwap^0.5───────────────────────────────────────────────\n",
       "                                                 │                                                                                                 │\n",
       "(5, 1): ─────────────────────────────────────────┼────────────────────────────PhX(0)^0.5──────iSwap──────────────────────────────PhX(0.75)^0.5─────┼─────────────PhX(-0.25)^0.5────Z─────────────────iSwap────────────PhX(1)^-0.5──────────────────Z──────────────────────────\n",
       "                                                 │                                            │                                                    │                                                 │\n",
       "(5, 2): ────────────────────────PhX(-0.75)^0.5───iSwap^0.5────────────────────────────────────┼────────────────PhX(0.75)^0.5─────PhX(-0.25)^0.5────iSwap^0.5─────────────────────────────────────────┼─────────────────────────────────────────────PhX(-0.75)^-0.5────────────\n",
       "                                                                                              │                                                                                                      │\n",
       "(6, 1): ──────────────────────────────────────────────────────────────────────PhX(1)^0.5──────iSwap^0.5────────PhX(-0.75)^0.5────PhX(-0.5)^0.5─────PhX(-0.5)^-0.5──────────────────PhX(-0.75)^-0.5───iSwap^0.5─────────────────────────────────────X^0.5──────────────────────\n",
       "\n",
       "(6, 2): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5─────PhX(0)^0.5───────X^-0.5───────────────────────PhX(0.75)^-0.5─────────────\n",
       "                                                                                                                                                  └────────────────────────────┘                                     └─────────────────────────┘"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "optimized_circuit_with_spin_echoes = create_benchmark_circuit(\n",
    "    qubits, cycles=2, seed=1, with_optimization=True, with_alignment=True, with_spin_echoes=True\n",
    ")\n",
    "print(\n",
    "    f\"Circuit with optimization + alignment + spin echoes ({len(optimized_circuit_with_spin_echoes)} moments):\\n\"\n",
    ")\n",
    "optimized_circuit_with_spin_echoes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "-ZldoKJBNVkj"
   },
   "source": [
    "Now we create circuits for all cycle values without optimization, with optimization + alignment, and with optimization + alignment + spin echoes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "id": "GYmT7C5w2OxO"
   },
   "outputs": [],
   "source": [
    "\"\"\"Create all circuits.\"\"\"\n",
    "\n",
    "batch = [create_benchmark_circuit(qubits, cycles=c, seed=seed) for c in cycle_values]\n",
    "batch_with_optimization = [\n",
    "    create_benchmark_circuit(\n",
    "        qubits, cycles=c, seed=seed, with_optimization=True, with_alignment=True\n",
    "    )\n",
    "    for c in cycle_values\n",
    "]\n",
    "batch_with_optimization_and_spin_echoes = [\n",
    "    create_benchmark_circuit(\n",
    "        qubits,\n",
    "        cycles=c,\n",
    "        seed=seed,\n",
    "        with_optimization=True,\n",
    "        with_alignment=True,\n",
    "        with_spin_echoes=True,\n",
    "    )\n",
    "    for c in cycle_values\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "LE3Af6DvNenw"
   },
   "source": [
    "The next cell runs them on the device."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "id": "p-vEk4p12tF3"
   },
   "outputs": [],
   "source": [
    "\"\"\"Run all circuits.\"\"\"\n",
    "\n",
    "all_probs = []\n",
    "for b in (batch, batch_with_optimization, batch_with_optimization_and_spin_echoes):\n",
    "    results = device_sampler.sampler.run_batch(b, repetitions=nreps)\n",
    "    all_probs.append([to_survival_prob(*res) for res in results])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "wwAV401nNhGI"
   },
   "source": [
    "And the next cell plots the results."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "id": "m3DFhHXk3DC9"
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEGCAYAAABo25JHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOydd3wU1fbAv3c3vQNJICSUQEJPaAGkPUCkBhFBUZ4NUbECNhSfihH1iaIoKsLziSI+f4gCIgoqUhQFFQKhBKTXhJqEVFI22fv7YzYhZXezKZtNud/PZz67c+fOnbNDmDP3nHPPEVJKFAqFQtFw0TlaAIVCoVA4FqUIFAqFooGjFIFCoVA0cJQiUCgUigaOUgQKhULRwHFytAAVxd/fX7Zu3drRYigUCkWdYteuXUlSygBzx+qcImjdujWxsbGOFkOhUCjqFEKI05aOKdOQQqFQNHCUIlAoFIoGjlIECoVC0cCxm49ACPEJMAa4JKXsYua4ABYAo4GrwGQp5W57yaOwHYPBQEJCAjk5OY4WRaFQVBA3NzdCQkJwdna2+Rx7OouXAh8AyywcHwWEm7Y+wCLTp8LBJCQk4O3tTevWrdH0tUKhqAtIKUlOTiYhIYHQ0FCbz7ObaUhKuRVIsdLlJmCZ1PgT8BNCBNlDlnUn1jF85XAiP4tk+MrhrDuxzh6XqTfk5OTQpEkTpQQUijqGEIImTZpUeDbvyPDRYOBssf0EU9v50h2FEFOBqQAtW7as0EXWnVhHzO8vkiMNAJzPOk/M7y8CEN0mujJyNwiUElAo6iaV+b9bJ5zFUsqPpJRRUsqogACz6yEssuDP14uUQCE50sCCP1+vThEVCoWizuJIRZAItCi2H2Jqq1Yu5KVWqF1ROzh16hRdupSMMYiJieGtt96qtmukpqby4YcfFu2fO3eOW265pUJjzJ49m40bN1ZZFi8vryqPoVBUFkcqgrXA3ULjOiBNSlnGLFRVmuUXVKhdUXHWxCXSf+5mQmeto//czayJq3Z9bhdKK4LmzZuzcuXKCo0xZ84cbrjhhuoWTaGoUeymCIQQy4E/gPZCiAQhxH1CiIeEEA+ZuqwHTgDHgP8Cj9hDjhm5etyMxhJtLkbJjFy9PS7X4FgTl8hzq/eTmJqNBBJTs3lu9X67KoPBgwfz7LPP0rt3b9q1a8dvv/0GaE7ue++9l4iICLp3786WLVsAWLp0KTfddBODBw8mPDycl19+GYBZs2Zx/PhxunXrxsyZM0vMQpYuXcq4ceMYNmwYrVu35oMPPmD+/Pl0796d6667jpQULQ5i8uTJrFy5ktjYWLp160a3bt2IiIgostMeP36ckSNH0rNnTwYOHMihQ4cAOHnyJH379iUiIoIXXnjBbvdKobAFuzmLpZSTyjkugUftdf1CogfOho0zWeDjwQUnPQJoWlDA6AEx9r50veDl7w5w8Fy6xeNxZ1LJKyipaLMNBTyzch/Ld5wxe06n5j68dGPnKsmVn5/Pjh07WL9+PS+//DIbN25k4cKFCCHYv38/hw4dYvjw4Rw5cgSAHTt2EB8fj4eHB7169SI6Opq5c+cSHx/Pnj17AM0cVZz4+Hji4uLIyckhLCyMN954g7i4OJ544gmWLVvG448/XtQ3KiqqaJyZM2cycuRIAKZOncrixYsJDw/nr7/+4pFHHmHz5s3MmDGDhx9+mLvvvpuFCxdW6V4oFFWlTjiLq0TkRKJvmMeGDD37TiXwfEoaZ52d2N4k2NGS1QtKK4Hy2m3FUuRDYfv48eMB6NmzZ9ED/Pfff+fOO+8EoEOHDrRq1apIEQwbNowmTZrg7u7O+PHj+f3338uVYciQIXh7exMQEICvry833ngjABEREWWURiErVqxg9+7dzJ07l8zMTLZv386tt95Kt27dePDBBzl/XrN+btu2jUmTtHelu+66y4Y7olDYjzqXfbRSRE7UNuDm3f/j47jX+PCv1+kX/L0KkyyH8t7c+8/dTGJqdpn2YD93VjzYt9LXbdKkCVeuXCnRlpKSUrRIxtXVFQC9Xk9+fn6545X+d7bl373wGgA6na5oX6fTmb1mfHw8MTExbN26Fb1ej9FoxM/Pr2imUJ5MCoWjqP8zglI4d72NB3Kd2Jd5ht8Tf3O0OHWemSPa4+5c0t/i7qxn5oj2VRrXy8uLoKAgNm/eDGhK4Mcff2TAgAEWzxk4cCBffPEFAEeOHOHMmTO0b6/J8fPPP5OSkkJ2djZr1qyhf//+eHt7k5GRUSU5C0lNTWXSpEksW7aMwhBnHx8fQkND+frrrwFt1efevXsB6N+/P19++SVAkcwKhaNocIoAvTPjoqbR3JDPoh1vorkqFJVlXPdgXh8fQbCfOwJtJvD6+AjGda+66W3ZsmW88sordOvWjeuvv56XXnqJtm3bWuz/yCOPYDQaiYiI4LbbbmPp0qVFb/G9e/dmwoQJREZGMmHCBKKiomjSpAn9+/enS5cuzJw5s0qyfvvtt5w+fZoHHnigyGkM2kN+yZIldO3alc6dO/Ptt98CsGDBAhYuXEhERASJiXUjykpRfxF17UEYFRUlq1yYxpDDqv90J8bbiYVDF/KPkH9Uj3D1hL///puOHTs6WoxqY+nSpcTGxvLBBx84WhSFokYw939YCLFLShllrn/DmxEAOLsxtvtDBBvy+XDHPDUrUCgUDZqGqQgA51738+DVfA5knGJrwlZHi6OwI5MnT1azAYXCCg1WEeDiyZjI+wkxGPgw9m01K1AoFA2WhqsIAOc+DzI108DB9JP8cvYXR4ujUCgUDqFBKwLc/bix8520MBhYtOsdNStQKBQNkgahCKwlRXPqN40H07P5O/0km89udqCUCoVC4RjqvSIoNymapz/RHW6jlSGfRbsWYJRVS42gqB4SEhK46aabCA8Pp23btsyYMYO8vDyr5zgyrfSaNWs4ePBglcepDpKSknB2dmbx4sUl2lu3bk1SUhIA/fr1c4RoVtmzZw/r1693tBgNknqvCOb9dJhsQ8mU09mGAub9dLho36n/DB5My+Rw+kk2n1Gzggqz7yt4pwvE+Gmf+76q0nBSSsaPH8+4ceM4evQoR44cITMzk+eff97qeY5MK11aEdgjPXVMTAxLly4tt9/XX3/Nddddx/Llyy322b59ezVKVj0oReA46r0iOGcmD06Zdt9gRoXdRGtDPh/ufk/NCirCvq/gu+mQdhaQ2ud306ukDDZv3oybmxv33nsvoOUTeuedd/jkk0+4evWqQ9NK//e//6VXr1507dqVCRMmcPXqVbZv387atWuZOXMm3bp14/jx40XjAGzatInu3bsTERHBlClTyM3NBbQ39JdeeokePXoQERFRlKK6qixfvpy3336bxMREEhISzPYpLIRjNBp55JFH6NChA8OGDWP06NFFcluSLyYmhnvuuYeBAwfSqlUrVq9ezTPPPENERAQjR47EYNAqAu7atYtBgwbRs2dPRowYUZRwz1wa8by8PGbPns2KFSvo1q0bK1asqJZ7obCNeq8Imvu529TuNOAJHkxN42j6STaedsyUvlbywyz4NNry9u1jYCilbA3ZWrulc36Y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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"Plot results.\"\"\"\n",
    "\n",
    "labels = [\"Unoptimized\", \"Optimization + Alignment\", \"Optimization + Alignment + Spin echoes\"]\n",
    "\n",
    "for probs, label in zip(all_probs, labels):\n",
    "    plt.plot(cycle_values, probs, \"-o\", label=label)\n",
    "\n",
    "plt.xlabel(\"Cycles\")\n",
    "plt.ylabel(\"Survival probability\")\n",
    "plt.legend();"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "GQntSKQU3DlE"
   },
   "source": [
    "Recall that without any noise, the survival probability (ratio of $1$s measured to all measurements) should be $1.0$, so higher on this plot is better. The unoptimized circuit performs the worst, the circuit with optimization + alignment performs better, and the circuit with optimization + alignment + spin echoes performs the best."
   ]
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "name": "spin_echoes.ipynb",
   "toc_visible": true
  },
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
